accop, xaccop, lsfpa, ssfpa, ldfpa, sdfpa, lefpa, sefpa, lefpal,
lsfpo, ldfpo, lefpo,
and lefpol.accop
routine copies the value in the floating point accumulator
to the floating point operand register. This routine is useful when you
want to use the result of one computation as the second operand of a second
computation.xaccop
routine exchanges the values in the floating point
accumuator and operand registers. Note that many floating point computations
destory the value in the floating point operand register, so you cannot
blindly assume that the routines preserve the operand register. Therefore,
calling this routine only makes sense after performing some computation
which you know does not affect the floating point operand register.Lsfpa, ldfpa, and lefpa
load the floating point accumulator
with a single, double, or extended precision floating point value, respectively.
The UCR Standard Library uses its own internal format for computations.
These routines convert the specified values to the internal format during
the load. On entry to each of these routines, es:di
must contain
the address of the variable you want to load into the floating point accumulator.
The following code demonstrates how to call these routines:rVar real4 1.0 drVar real8 2.0 xrVar real10 3.0 . . . lesi rVar lsfpa . . . lesi drVar ldfpa . . . lesi xrVar lefpaThe
lsfpo, ldfpo,
and lefpo
routines are similar
to the lsfpa
, ldfpa
, and lefpa
routines
except, of course, they load the floating point operand register rather
than the floating point accumulator with the value at address es:di
.Lefpal
and lefpol
load the floating point accumulator
or operand register with a literal 80 bit floating point constant appearing
in the code stream. To use these two routines, simply follow the call with
a real10
directive and the appropriate constant, e.g., lefpal real10 1.0 lefpol real10 2.0e5The
ssfpa
, sdfpa
, and sefpa
routines
store the value in the floating point accumulator into the memory based
floating point variable whose address appears in es:di
. There
are no corresponding ssfpo, sdfpo, or sefpo routines because a result you
would want to store should never appear in the floating point operand register.
If you happen to get a value in the floating point operand that you want
to store into memory, simply use the xaccop routine to swap the accumulator
and operand registers, then use the store accumulator routines to save the
result. The following code demonstrates the use of these routines:rVar real4 1.0 drVar real8 2.0 xrVar real10 3.0 . . . lesi rVar ssfpa . . . lesi drVar sdfpa . . . lesi xrVar sefpa
itof,
utof, ltof, ultof, ftoi, ftou, ftol,
and ftoul.
The
first four routines convert signed and unsigned integers to floating point
format, the last four routines truncate floating point values and convert
them to an integer value.Itof
converts the signed 16-bit value in ax
to
a floating point value and leaves the result in the floating point accumulator.
This routine does not affect the floating point operand register. Utof
converts the unsigned integer in ax
in a similar fashion. Ltof
and ultof
convert the 32 bit signed (ltof
) or
unsigned (ultof
) integer in dx:ax
to a floating
point value, leaving the value in the floating point accumulator. These
routines always succeed.Ftoi
converts the value in the floating point accumulator to
a signed integer value, leaving the result in ax
. Conversion
is by truncation; this routine keeps the integer portion and throws away
the fractional part. If an overflow occurs because the resulting integer
portion does not fit into 16 bits, ftoi
returns the carry flag
set. If the conversion occurs without error, ftoi
return the
carry flag clear. Ftou
works in a similar fashion, except it
converts the floating point value to an unsigned integer in ax
;
it returns the carry set if the floating point value was negative.Ftol
and ftoul
converts the value in the floating
point accumulator to a 32 bit integer leaving the result in dx:ax
.
Ftol
works on signed values, ftoul
works with
unsigned values. As with ftoi
and ftou
, these
routines return the carry flag set if a conversion error occurs.fpadd
, fp
sub
, fpcmp
, fpmul
, and fpdiv
routines. Fpadd
adds the value in the floating point accumulator
to the floating point accumulator. Fpsub
subtracts the value
in the floating point operand from the floating point accumulator. Fpmul
multiplies the value in the floating accumulator by the floating point operand.
Fpdiv
divides the value in the floating point accumulator by
the value in the floating point operand register. Fpcmp
compares
the value in the floating point accumulator against the floating point operand.fpcmp
) compares the
floating point accumulator against the floating point operand and returns
-1, 0, or 1 in the ax
register if the accumulator is less than,
equal, or greater than the floating point operand. It also compares ax with
zero immediately before returning so it sets the flags so you can use the
jg, jge, jl, jle, je,
and jne
instructions immediately
after calling fpcmp
. Unlike fpadd
, fpsub
,
fpmul
, and fpdiv
, fpcmp
does not
destroy the value in the floating point accumulator or the floating point
operand register. Keep in mind the problems associated with comparing floating
point numbers!ftoa
,
etoa
, and atof
, that let you convert floating
point numbers to ASCII strings and vice versa; it also provides a special
version of printf
, printff
, that includes the
ability to print floating point values as well as other data types.Ftoa
converts a floating point number to an ASCII string which
is a decimal representation of that floating point number. On entry, the
floating point accumulator contains the number you want to convert to a
string. The es:di
register pair points at a buffer in memory
where ftoa
will store the string. The al
register
contains the field width (number of print positions). The ah
register contains the number of positions to display to the right of the
decimal point. If ftoa
cannot display the number using the
print format specified by al
and ah
, it will create
a string of "#" characters, ah characters long. Es:di
must point at a byte array containing at least al+1
characters
and al should contain at least five. The field width and decimal length
values in the al and ah registers are similar to the values appearing after
floating point numbers in the Pascal write statement, e.g.,write(floatVal:al:ah);
Etoa
outputs the floating point number in exponential form.
As with ftoa
, es:di
points at the buffer where
etoa
will store the result. The al
register must
contain at least eight and is the field width for the number. If al
contains less than eight, etoa
will output a string of "#"
characters. The string that es:di
points at must contain at
least al+1
characters. This conversion routine is similar to
Pascal's write procedure when writing real values with a single field width
specification:write(realvar:al);The Standard Library
printff
routine provides all the facilities
of the standard printf routine plus the ability to handle floating point
output. The printff routine includes several new format specifications to
print floating point numbers in decimal form or using scientific notation.
The specifications areftoa
in al
and ah
. The z value is comparable to the
value etoa
expects in the al
register.printff
routine is identical to the printf
routine. If you use the
printff
routine in your assembly language programs, you should
not use the printf
routine as well. Printff
duplicates
all the facilities of printf
and using both would only waste
memory.